package com.wmh.baseservice.user.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wmh.baseservice.common.annotation.parameterverify.ParameterVerify;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.utils.CommUtil;
import com.wmh.baseservice.common.utils.QrCodeUtil;
import com.wmh.baseservice.common.utils.UUIDUtil;
import com.wmh.baseservice.common.utils.encrypt.Base64Util;
import com.wmh.baseservice.common.utils.page.pojo.PageInfo;
import com.wmh.baseservice.common.utils.page.pojo.PageResult;
import com.wmh.baseservice.common.utils.page.pojo.SortWay;
import com.wmh.baseservice.common.utils.page.util.PageUtil;
import com.wmh.baseservice.common.utils.returnbody.ResultCodeInfo;
import com.wmh.baseservice.common.utils.returnbody.ReturnBody;
import com.wmh.baseservice.merchant.pojo.*;
import com.wmh.baseservice.merchant.service.*;
import com.wmh.baseservice.system.service.SysCategoryService;
import com.wmh.baseservice.user.pojo.UsAddress;
import com.wmh.baseservice.user.pojo.UsInfo;
import com.wmh.baseservice.user.pojo.UsShopCar;
import com.wmh.baseservice.user.pojo.UsVegetableOrder;
import com.wmh.baseservice.user.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wmh generator
 * @since 2021-12-31
 */
@Api(tags = "用户端-附近好地相关接口")
@RestController
@RequestMapping(value = "user/plot", produces = "text/plain;charset=utf-8")
public class UsPlotController {

    @Resource
    private MerchantVegetablePlotService merchantVegetablePlotService;
    @Resource
    private MerchantVegetableService merchantVegetableService;
    @Resource
    private UsInfoService usInfoService;
    @Resource
    private HttpServletRequest request;
    @Resource
    private UsEvaluateService usEvaluateService;
    @Resource
    private SysCategoryService sysCategoryService;
    @Resource
    private UsVegetableOrderService usVegetableOrderService;
    @Resource
    private MerchantPrviteUserService merchantPrviteUserService;
    @Resource
    private MerchantPlotRegionService merchantPlotRegionService;
    @Resource
    private UsShopCarService usShopCarService;
    @Resource
    private UsAddressService usAddressService;
    @Resource
    private MerchantInfoService merchantInfoService;

    @ApiOperation("土地列表")
    @PostMapping("plotList")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "lat", value = "维度", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "lng", value = "经度", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "type", value = "土地类型 0采摘 1种植 2全部", required = true),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "search", value = "搜索内容", required = false),
    })
    @ParameterVerify(notNull = "type")
    public String plotList(PageInfo pageInfo, String lat, String lng, Integer type, String search) {
        //封装参数
        Map<String, Object> map = new HashMap<>(16);
        Long usId = (Long) request.getAttribute("usId");
        map.put("usId", usId);
        map.put("type", type);
        if (CommUtil.checkNull(lat, lng)) {
            map.put("lat", lat);
            map.put("lng", lng);
        }
        if (CommUtil.checkNull(search)) {
            map.put("search", search);
        }
        //分页
        PageResult<MerchantVegetablePlot> pageResult = new PageResult<>();
        Page<MerchantVegetablePlot> vegetablePage = new Page<>(pageInfo.getPageNo(), pageInfo.getPageSize());
        IPage<MerchantVegetablePlot> merchantPlotRegionIPage = merchantVegetablePlotService.usPlotList(vegetablePage, map);
        //如果有经纬度按距离排序，如果没有则按创建时间排序
        if (CommUtil.checkNull(lat, lng)) {
            merchantPlotRegionIPage.getRecords().sort(Comparator.comparing(MerchantVegetablePlot::getJuli).reversed());
        } else {
            merchantPlotRegionIPage.getRecords().sort(Comparator.comparing(MerchantVegetablePlot::getCreateTime).reversed());
        }
        pageResult.setPageSize(merchantPlotRegionIPage.getSize()).setPageNo(merchantPlotRegionIPage.getCurrent()).setPages(merchantPlotRegionIPage.getPages()).
                setTotal(merchantPlotRegionIPage.getTotal());
        pageResult.setList(merchantPlotRegionIPage.getRecords());
        return ReturnBody.success(pageResult);
    }

    @ApiOperation("土地详情")
    @PostMapping("plotDetail")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "土地id", required = true),
    })
    @ParameterVerify(notNull = "id")
    public String plotDetail(Long id, String lat, String lng) {
        Long usId = (Long) request.getAttribute("usId");
        Map<String, Object> map = new HashMap<>(16);
        map.put("usId", usId);
        map.put("id", id);
        if (CommUtil.checkNull(lat, lng)) {
            map.put("lat", lat);
            map.put("lng", lng);
        }
        MerchantVegetablePlot merchantVegetablePlot = merchantVegetablePlotService.plotDetail(map);
        if (merchantVegetablePlot.getOpenType() == 2) {
            MerchantPrviteUser merchantPrviteUser = merchantPrviteUserService.getOneForUpdate(new QueryWrapper<MerchantPrviteUser>().eq(MerchantPrviteUser.PLOT_ID, id).eq(MerchantPrviteUser.US_ID, usId));
            if (!CommUtil.checkNull(merchantPrviteUser)) {
                return ReturnBody.error(ResultCodeInfo.NO_AUTHORITY_OPERATE_PERMISSION);
            }
        }
        if (!CommUtil.checkNull(merchantVegetablePlot)) {
            return ReturnBody.error(ResultCodeInfo.PARAM_ERROR);
        }
        merchantVegetablePlot.setRawMerchantId(merchantVegetablePlotService.getMerchantId(merchantVegetablePlot.getId()));
        return ReturnBody.success(merchantVegetablePlot);
    }


    @ApiOperation("提交订单")
    @PostMapping("subOrder")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "果蔬id", required = true),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "amount", value = "重量", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "type", value = "1采摘 2种植", required = true),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "img", value = "轮播图", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "remark", value = "备注", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "hasTake", value = "是否自提 1自提", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "payType", value = "1余额支付 2微信支付", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "province", value = "省", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "city", value = "市", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "area", value = "区", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "address", value = "详细地址", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "name", value = "收货人", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "phone", value = "收货电话", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "hasCourier", value = "是否发快递1发 -1无", required = false),
    })
    @ParameterVerify(notNull = {"id", "type"})
    public String subOrder(Long id, Double amount, Integer type, String img, String remark, Integer hasTake,
                           Integer payType, String city, String area, String province, String address, String name,
                           String phone, Integer hasCourier) {
        if (type == 1) {
            if (!CommUtil.checkNull(amount)) {
                return ReturnBody.error("请填写重量");
            }
        }


        Long usId = (Long) request.getAttribute("usId");
        MerchantVegetable merchantVegetable = merchantVegetableService.getByIdForUpdate(id);
        if (!CommUtil.checkNull(merchantVegetable) || merchantVegetable.getStatus() != 0) {
            return ReturnBody.error("该商品已下架或不存在");
        }
        //查询用户短时间内是否已提交过订单
        int orderCount = usVegetableOrderService.queryShortOrder(usId);
        if (orderCount != 0) {
            return ReturnBody.error("您刚刚已提交过订单，为保证正常交易，请等待半分钟后再提交");
        }
        switch (type) {
            case 1:
                if (merchantVegetable.getType() != 0 && merchantVegetable.getType() != 2) {
                    return ReturnBody.error("该产品暂不支持该下单类型");
                }
                break;
            case 2:
                if (merchantVegetable.getType() != 1 && merchantVegetable.getType() != 2) {
                    return ReturnBody.error("该产品暂不支持该下单类型");
                }
                break;
            default:
                return ReturnBody.error(ResultCodeInfo.PARAM_ERROR);
        }
        //查询所属区域
        MerchantPlotRegion merchantPlotRegion = merchantPlotRegionService.getByIdForUpdate(merchantVegetable.getRegionId());
        if (!CommUtil.checkNull(merchantPlotRegion)) {
            return ReturnBody.error(ResultCodeInfo.SERVICE_EXCEPTION);
        }
        UsVegetableOrder usVegetableOrder = new UsVegetableOrder();
        //封装参数
        if (type == 1) {
            usVegetableOrder.setTotalPrice(merchantVegetable.getPrice().multiply(new BigDecimal(amount)));
        } else {
            usVegetableOrder.setTotalPrice(merchantVegetable.getGrowPrice());
        }
        usVegetableOrder.setRealPrice(usVegetableOrder.getTotalPrice());
        usVegetableOrder.setPlotId(merchantVegetable.getPlotId());
        usVegetableOrder.setOrderNum(UUIDUtil.getTimeId() + UUIDUtil.getLetter());
        usVegetableOrder.setUsId(usId).setType(type).setRemark(remark);
        usVegetableOrder.setMerchantId(merchantPlotRegion.getMerchantId());
        usVegetableOrder.setMerchantType(merchantPlotRegion.getStatus() == 2 ? 1 : 0);


        //用户上传的图片
        if (CommUtil.checkNull(img)) {
            JSONArray imgArray = JSONArray.parseArray(img);
            StringBuilder sb = new StringBuilder();
            imgArray.forEach(item -> {
                if (!item.toString().contains("base64")) {
                    throw new ServiceException("图片格式错误");
                }
                String imgString = Base64Util.generateImage("order/", item.toString());
                if (CommUtil.checkNull(imgString)) {
                    sb.append(imgString).append(",");
                }
            });
            if (sb.length() != 0) {
                String imgUrl = sb.replace(sb.length() - 1, sb.length(), "").toString();
                usVegetableOrder.setImg(imgUrl);
            }
        }

        JSONArray array = new JSONArray();
        JSONObject object = new JSONObject(true);
        if (type == 1) {
            object.put("amount", amount);
        }

        object.put("standardPrice", type == 1 ? merchantVegetable.getPrice() : merchantVegetable.getGrowPrice());
        object.put("overview", merchantVegetable.getOverview());
        object.put("price", usVegetableOrder.getTotalPrice());
        object.put("avatar", merchantVegetable.getAvatar());
        object.put("id", merchantVegetable.getId());
        object.put("title", merchantVegetable.getTitle());
        array.add(object);
        usVegetableOrder.setSnapshot(array.toJSONString()).setHasTake(CommUtil.checkNull(hasTake) ? 1 : null);
        if (CommUtil.checkNull(usVegetableOrder.getHasTake())) {
            //自提单生成二维码
            try {
                JSONObject qrCode = new JSONObject(true);
                qrCode.put("orderNum", usVegetableOrder.getOrderNum());
                qrCode.put("type", "vegetable");
                String paramsQrCode = QrCodeUtil.createParamsQrCode(qrCode.toJSONString(), "/order/", usVegetableOrder.getOrderNum());
                usVegetableOrder.setQrCode(paramsQrCode);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        usVegetableOrder.setPayType(payType);


        //处理地址
        if (CommUtil.checkNull(city, area, phone, usId, hasCourier) && hasCourier == 1) {
            QueryWrapper<UsAddress> eq = new QueryWrapper<UsAddress>().eq(UsAddress.PROVINCE, province).eq(UsAddress.CITY, city).eq(UsAddress.AREA, area).eq(UsAddress.ADDRESS, address).eq(UsAddress.NAME, name)
                    .eq(UsAddress.PHONE, phone).eq(UsAddress.US_ID, usId);
            UsAddress usAddress = usAddressService.getOneForUpdate(eq);
            if (!CommUtil.checkNull(usAddress)) {
                usAddress = new UsAddress();
                usAddress.setAddress(address).setPhone(phone).setProvince(province).setCity(city).setArea(area).setUsId(usId).setName(name);
                if (!usAddressService.save(usAddress)) {
                    return ReturnBody.error(ResultCodeInfo.SERVICE_EXCEPTION);
                }
            }
            usVegetableOrder.setAddressId(usAddress.getId());
        }
        if (!usVegetableOrderService.save(usVegetableOrder)) {
            return ReturnBody.error(ResultCodeInfo.SERVICE_EXCEPTION);
        }
        merchantVegetableService.updateById(merchantVegetable.setSale(merchantVegetable.getSale() + 1));
        return ReturnBody.success(usVegetableOrder.getOrderNum());
    }

    @ApiOperation("余额支付")
    @PostMapping("balancePay")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "orderNum", value = "订单号", required = true),
    })
    @ParameterVerify(notNull = "orderNum")
    public String balancePay(String orderNum) {
        Long usId = (Long) request.getAttribute("usId");
        UsVegetableOrder usVegetableOrder = usVegetableOrderService.getOneForUpdate(new QueryWrapper<UsVegetableOrder>().eq(UsVegetableOrder.ORDER_NUM, orderNum));
        if (!CommUtil.checkNull(usVegetableOrder) || usVegetableOrder.getStatus() != 0) {
            return ReturnBody.error("订单不存在或状态错误");
        }
        UsInfo usInfo = usInfoService.getByIdForUpdate(usId);
        if (usInfo.getBalance().compareTo(usVegetableOrder.getRealPrice()) < 0) {
            return ReturnBody.error("余额不足");
        }
        //支付类型改为余额支付
        usVegetableOrder.setPayType(1);
        usVegetableOrderService.balancePay(usVegetableOrder, usInfo);
        return ReturnBody.success();
    }

    @ApiOperation("确认收货")
    @PostMapping("confirm")
    public String confirm(String orderNum) {
        Long usId = (Long) request.getAttribute("usId");
        UsVegetableOrder usVegetableOrder = usVegetableOrderService.getOneForUpdate(new QueryWrapper<UsVegetableOrder>().eq(UsVegetableOrder.ORDER_NUM, orderNum));
        if (!CommUtil.checkNull(usVegetableOrder) || usVegetableOrder.getStatus() != 1 || !usVegetableOrder.getUsId().equals(usId)) {
            return ReturnBody.error("订单不存在或状态错误");
        }
        usVegetableOrder.setStatus(3);
        if (CommUtil.checkNull(usVegetableOrder.getAddressId())) {
            usVegetableOrder.setCourierStatus(2);
        } else {
            usVegetableOrder.setTakeTime(new Date());
        }
        usVegetableOrderService.confirm(usVegetableOrder);
        return ReturnBody.success();
    }

    @ApiOperation("产品列表")
    @PostMapping("productList")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "categoryId", value = "分类id", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "plotId", value = "土地id", required = true),
    })
    @ParameterVerify(notNull = "plotId")
    public String productList(PageInfo pageInfo, Long categoryId, Long plotId, Integer type) {
        Long usId = (Long) request.getAttribute("usId");
        pageInfo.setTimeScreen("create_time");
        pageInfo.setDefaultSort("create_time", SortWay.DESC);
        //执行分页辅助工具
        PageResult<MerchantVegetable> pageResult = new PageUtil<MerchantVegetable>(pageInfo).startPage((page, queryWrapper) -> {
            queryWrapper.select(MerchantVegetable.TITLE, MerchantVegetable.SALE, MerchantVegetable.GROW_PRICE, MerchantVegetable.PRICE
                    , MerchantVegetable.ID, MerchantVegetable.CATEGORY_ID, MerchantVegetable.AVATAR, MerchantVegetable.MERCHANT_ID
                    , MerchantVegetable.PLOT_ID, MerchantVegetable.INVENTORY);
            queryWrapper.eq(MerchantVegetable.PLOT_ID, plotId).eq(MerchantVegetable.STATUS, 0);
            queryWrapper.in(MerchantVegetable.TYPE, type, 2);
            if (CommUtil.checkNull(categoryId)) {
                queryWrapper.eq(MerchantVegetable.CATEGORY_ID, categoryId);
            }
            merchantVegetableService.page(page, queryWrapper);
        });
        pageResult.getList().forEach(item -> {
            UsShopCar usShopCar = usShopCarService.getOneForUpdate(new QueryWrapper<UsShopCar>()
                    .eq(UsShopCar.US_ID, usId).eq(UsShopCar.TYPE, 3).eq(UsShopCar.GOODS_ID, item.getId()).eq(UsShopCar.PLOT_ID, item.getPlotId())
                    .eq(UsShopCar.SPECIAL_TYPE, type));
            item.setCarCount(CommUtil.checkNull(usShopCar) ? usShopCar.getCount() : 0.00);
        });
        pageResult.setList(pageResult.getList().stream().sorted(Comparator.comparing(MerchantVegetable::getCategoryId)).collect(Collectors.toList()));
        return ReturnBody.success(pageResult);
    }

    @ApiOperation("是否为该土地当前持有人")
    @PostMapping("haveCurrentPlot")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "id", required = false),
    })
    public String haveCurrentPlot(Long plotId) {
        Long usId = (Long) request.getAttribute("usId");
        JSONObject object = new JSONObject(true);
        int count=0;
        //获取用户商家信息
        UsInfo usInfo = usInfoService.getById(usId);
        //TODO 如果当前用户是商家并且拥有该土地任意一块区域，那么果蔬购物列表即展示生成海报图标
        if (CommUtil.checkNull(usInfo.getMerchantId())) {
            count = merchantPlotRegionService.count(new QueryWrapper<MerchantPlotRegion>()
                    .eq(MerchantPlotRegion.PLOT_ID, plotId)
                    .eq(MerchantPlotRegion.MERCHANT_ID, usInfo.getMerchantId()));

            object.put("count",count);
            //商家信息
            MerchantInfo merchantInfo = merchantInfoService.getById(usInfo.getMerchantId());
            MerchantVegetablePlot merchantVegetablePlot = merchantVegetablePlotService.getById(plotId);
            object.put("avatar",merchantVegetablePlot.getAvatar());
            object.put("title",merchantVegetablePlot.getPlotName());
            object.put("banner",merchantVegetablePlot.getBanner());
            object.put("name",merchantInfo.getName());
            object.put("phone",merchantInfo.getPhone());
            object.put("shareBanner",merchantVegetablePlot.getShareBanner());
        }else{
            object.put("count",count);
        }
        return ReturnBody.success(object);
    }


}



